package cn.exrick.xboot.modules.base.serviceimpl;

import cn.exrick.xboot.common.exception.XbootException;
import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.common.vo.RoleDTO;
import cn.exrick.xboot.modules.base.dao.UserDao;
import cn.exrick.xboot.modules.base.dao.mapper.UserMapper;
import cn.exrick.xboot.modules.base.dao.mapper.UserRoleMapper;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.entity.UserRole;
import cn.exrick.xboot.modules.base.enums.RoleEnum;
import cn.exrick.xboot.modules.base.enums.StatusEnum;
import cn.exrick.xboot.modules.base.param.ChangeScopeParam;
import cn.exrick.xboot.modules.base.param.QueryUserParam;
import cn.exrick.xboot.modules.base.param.UpdateAdminParam;
import cn.exrick.xboot.modules.base.service.UserService;
import cn.exrick.xboot.modules.base.vo.UserVo;
import cn.exrick.xboot.modules.transport.entity.BigCustomerUsers;
import cn.exrick.xboot.modules.transport.service.BigCustomerUsersService;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户接口实现
 * @author Exrickx
 */
@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private BigCustomerUsersService bigCustomerUsersService;



    @Override
    public UserDao getRepository() {
        return userDao;
    }

    @Override
    public User findByUsername(String username) {

        User user = userDao.findByUsername(username);
        return userToDTO(user);
    }

    @Override
    public User findByMobile(String mobile) {

        User user = userDao.findByMobile(mobile);
        return userToDTO(user);
    }


    public User userToDTO(User user) {

        if (user == null) {
            return null;
        }
        List<RoleDTO> roleDTOList = new ArrayList<>();
        // 关联角色
        List<UserRole> roleList = userRoleMapper.findByUserId(user.getId());
        if (CollectionUtil.isNotEmpty(roleList)){
            roleDTOList = roleList.stream().map(RoleDTO::new).collect(Collectors.toList());
            //当拥有PLATFORM_ADMIN role的时候为管理员
            if (roleDTOList.stream().anyMatch(roleDTO -> roleDTO.getRoleName().equals(RoleEnum.PLATFORM_ADMIN.getValue()))){
                user.setIsAdmin(true);
            }
            //用户的角色中 status = 1 为当前生效角色，这里设置用户当前角色
            Optional<RoleDTO> currentRole = roleDTOList.stream().filter(roleDTO -> StatusEnum.ENABLE.getValue().equals(roleDTO.getStatus())).findFirst();
            currentRole.ifPresent(user::setCurrentRole);
        }
        user.setRoles(roleDTOList);
        user.setIsBigCustomers(bigCustomerUsersService.lambdaQuery().eq(BigCustomerUsers::getUserId, user.getId()).one());
        user.setPermissions(new ArrayList<>());
        return user;
    }

    @Override
    public Page<UserVo> findByCondition(Page page , QueryUserParam param) {
        return userMapper.findByCondition(page,param);
    }

    @Override
    public List<User> findByDepartmentId(Long departmentId) {

        return userDao.findByDepartmentId(departmentId);
    }

    @Override
    public void updateDepartmentTitle(Long departmentId, String departmentTitle) {

        userDao.updateDepartmentTitle(departmentId, departmentTitle);
    }

    @Override
    public User findByOpenId(String openid) {
        return userDao.findByWxOpenid(openid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User changeScope(ChangeScopeParam roles) {

        User currUser = securityUtil.getCurrUser();
        UserRole enable = new UserRole();
        enable.setStatus(StatusEnum.ENABLE.getValue());
        userRoleMapper.update(enable,new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleName,roles.getRoleName()).eq(UserRole::getUserId,currUser.getId()));
        UserRole disable = new UserRole();
        disable.setStatus(StatusEnum.DISABLE.getValue());
        userRoleMapper.update(disable,new LambdaQueryWrapper<UserRole>().ne(UserRole::getRoleName,roles.getRoleName()).eq(UserRole::getUserId,currUser.getId()));
        return currUser;
    }

    @Override
    public boolean updateAdmin(UpdateAdminParam param) {
        Optional<User> user = userDao.findById(param.getUserId());
        if (!user.isPresent()){
            throw new XbootException("操作失败,当前操作信息有误。");
        }
        if (param.getStatus().equals(StatusEnum.ENABLE.getValue())){
            if (Objects.isNull(userRoleMapper.selectOne(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId,param.getUserId()).eq(UserRole::getRoleName, RoleEnum.PLATFORM_ADMIN.getValue())))){
                userRoleMapper.insert(new UserRole().setUserId(param.getUserId()).setRoleName(RoleEnum.PLATFORM_ADMIN.getValue()));
            }
        }else {
            userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId,param.getUserId()).eq(UserRole::getRoleName, RoleEnum.PLATFORM_ADMIN.getValue()));
        }
        return true;
    }
}
